#include "vtkPolyData.h"
#include "vtkPolyDataReader.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTubeFilter.h"

#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkProperty.h"

#include "vtkPlane.h"
#include "vtkCutter.h"
#include "vtkClipPolyData.h"

#include "vtkOutlineFilter.h"
#include "vtkTransformFilter.h"
#include "vtkTransform.h"

#include <stdio.h>

int main(int argc, char *argv[])
{
    vtkPolyDataReader *pPolyDataReader = vtkPolyDataReader::New();
    pPolyDataReader->SetFileName(argv[1]);
	pPolyDataReader->Update();

	vtkTransform *transform = vtkTransform::New();
	vtkTransformFilter *transformModel = vtkTransformFilter::New();
	transform->Scale(1.0, 1.0, 2.0);
	transformModel->SetTransform(transform);
	transformModel->SetInputConnection(pPolyDataReader->GetOutputPort());

    vtkPolyDataMapper *pPolyDataMapper = vtkPolyDataMapper::New();
    pPolyDataMapper->SetInputConnection(transformModel->GetOutputPort());
	pPolyDataMapper->SetScalarVisibility(0);
	
    vtkActor *pActor = vtkActor::New();
    pActor->SetMapper(pPolyDataMapper);
	pActor->GetProperty()->SetColor(1.0, 1.0, 1.0);
	pActor->GetProperty()->SetAmbient(0.3);
	pActor->GetProperty()->SetInterpolationToPhong();


	double t[3] = {-1.025, -0.85, -0.265};
	double s[3] = {0.008547, 0.008547, 0.008547};

	// CC fibers
	const char *fiberFile1 = argv[2];
	vtkPolyDataReader *pFiberReader1 = vtkPolyDataReader::New();
	pFiberReader1->SetFileName(fiberFile1);
	vtkTubeFilter *pTube1 = vtkTubeFilter::New();
	pTube1->SetInputConnection(pFiberReader1->GetOutputPort());
	pTube1->SetRadius(0.4);
	pTube1->SetNumberOfSides(8);
	
	vtkTransform *transform1 = vtkTransform::New();
	vtkTransformFilter *transformModel1 = vtkTransformFilter::New();
	transform1->Translate(t);
	transform1->Scale(s);
	transformModel1->SetTransform(transform1);
	transformModel1->SetInputConnection(pTube1->GetOutputPort());

	vtkPolyDataMapper *pFiberMapper1 = vtkPolyDataMapper::New();
	pFiberMapper1->SetInputConnection(transformModel1->GetOutputPort());
	vtkActor *pFiberActor1 = vtkActor::New();
	pFiberActor1->SetMapper(pFiberMapper1);
	pFiberActor1->GetProperty()->SetColor(1.0, 1.0, 1.0);
	pFiberActor1->GetProperty()->SetAmbient(0.1);
	pFiberActor1->GetProperty()->SetInterpolationToPhong();


	// CG fibers
	const char *fiberFile2 = argv[3];
	vtkPolyDataReader *pFiberReader2 = vtkPolyDataReader::New();
	pFiberReader2->SetFileName(fiberFile2);
	vtkTubeFilter *pTube2 = vtkTubeFilter::New();
	pTube2->SetInputConnection(pFiberReader2->GetOutputPort());
	pTube2->SetRadius(0.4);
	pTube2->SetNumberOfSides(8);
	
	vtkTransform *transform2 = vtkTransform::New();
	vtkTransformFilter *transformModel2 = vtkTransformFilter::New();
	transform2->Translate(t);
	transform2->Scale(s);
	transformModel2->SetTransform(transform2);
	transformModel2->SetInputConnection(pTube2->GetOutputPort());

	vtkPolyDataMapper *pFiberMapper2 = vtkPolyDataMapper::New();
	pFiberMapper2->SetInputConnection(transformModel2->GetOutputPort());
	vtkActor *pFiberActor2 = vtkActor::New();
	pFiberActor2->SetMapper(pFiberMapper2);
	pFiberActor2->GetProperty()->SetColor(1.0, 1.0, 1.0);
	pFiberActor2->GetProperty()->SetAmbient(0.1);
	pFiberActor2->GetProperty()->SetInterpolationToPhong();


	// CR fibers
	const char *fiberFile3 = argv[4];
	vtkPolyDataReader *pFiberReader3 = vtkPolyDataReader::New();
	pFiberReader3->SetFileName(fiberFile3);
	vtkTubeFilter *pTube3 = vtkTubeFilter::New();
	pTube3->SetInputConnection(pFiberReader3->GetOutputPort());
	pTube3->SetRadius(0.4);
	pTube3->SetNumberOfSides(8);
	
	vtkTransform *transform3 = vtkTransform::New();
	vtkTransformFilter *transformModel3 = vtkTransformFilter::New();
	transform3->Translate(t);
	transform3->Scale(s);
	transformModel3->SetTransform(transform3);
	transformModel3->SetInputConnection(pTube3->GetOutputPort());

	vtkPolyDataMapper *pFiberMapper3 = vtkPolyDataMapper::New();
	pFiberMapper3->SetInputConnection(transformModel3->GetOutputPort());
	vtkActor *pFiberActor3 = vtkActor::New();
	pFiberActor3->SetMapper(pFiberMapper3);
	pFiberActor3->GetProperty()->SetColor(1.0, 1.0, 1.0);
	pFiberActor3->GetProperty()->SetAmbient(0.1);
	pFiberActor3->GetProperty()->SetInterpolationToPhong();

	// TF fibers
	const char *fiberFile4 = argv[5];
	vtkPolyDataReader *pFiberReader4 = vtkPolyDataReader::New();
	pFiberReader4->SetFileName(fiberFile4);
	vtkTubeFilter *pTube4 = vtkTubeFilter::New();
	pTube4->SetInputConnection(pFiberReader4->GetOutputPort());
	pTube4->SetRadius(0.4);
	pTube4->SetNumberOfSides(8);
	
	vtkTransform *transform4 = vtkTransform::New();
	vtkTransformFilter *transformModel4 = vtkTransformFilter::New();
	transform4->Translate(t);
	transform4->Scale(s);
	transformModel4->SetTransform(transform4);
	transformModel4->SetInputConnection(pTube4->GetOutputPort());

	vtkPolyDataMapper *pFiberMapper4 = vtkPolyDataMapper::New();
	pFiberMapper4->SetInputConnection(transformModel4->GetOutputPort());
	vtkActor *pFiberActor4 = vtkActor::New();
	pFiberActor4->SetMapper(pFiberMapper4);
	pFiberActor4->GetProperty()->SetColor(1.0, 1.0, 1.0);
	pFiberActor4->GetProperty()->SetAmbient(0.1);
	pFiberActor4->GetProperty()->SetInterpolationToPhong();

    vtkRenderer *pRenderer = vtkRenderer::New();
	pRenderer->SetAmbient(1.0, 1.0, 1.0);

    pRenderer->AddActor(pActor);
	pRenderer->AddActor(pFiberActor1);
	pRenderer->AddActor(pFiberActor2);
	pRenderer->AddActor(pFiberActor3);
	pRenderer->AddActor(pFiberActor4);

    vtkRenderWindow *pRenderWindow = vtkRenderWindow::New();
    pRenderWindow->AddRenderer(pRenderer);
    pRenderWindow->SetSize(1024, 1024);

    vtkRenderWindowInteractor *pRenderWindowInteractor = vtkRenderWindowInteractor::New();
    pRenderWindowInteractor->SetRenderWindow(pRenderWindow);

    pRenderWindow->Render();
    pRenderWindowInteractor->Start();
}


///************************************/
//float *vectors = NULL;
//float *mask = NULL;
//int w = 192;
//int h = 144;
//
//void ReadData()
//{
//	vectors = new float[6*w*h];
//	mask = new float[w*h];
//
//	FILE *fp = fopen("\\\\nabla.cs.purdue.edu\\visdata\\Ziang\\CoherenceStructure\\Datasets\\Alex\\2X\\Vectors.raw", "rb");
//	fread(vectors, sizeof(float), 6*w*h, fp);
//	fclose(fp);
//
//	fp = fopen("\\\\nabla.cs.purdue.edu\\visdata\\Ziang\\CoherenceStructure\\Datasets\\Alex\\2X\\mask.raw", "rb");
//	fread(mask, sizeof(float), w*h, fp);
//	fclose(fp);
//}
//
//int main(int argc, char *argv[])
//{
//	ReadData();
//
//	vtkPoints *pts = vtkPoints::New();
//	vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
//	colors->SetNumberOfComponents(3);
//	colors->SetName("Colors");
//	
//	pts->Initialize();
//	int count = 0;
//	for (int y = 0; y < h; ++y) {
//		for (int x = 0; x < w; ++x) {
//			int index = y * w + x;
//			if (mask[index] > 0.5f) {
//				pts->InsertNextPoint(x+vectors[index*6+0]*0.3f, y+vectors[index*6+2]*0.3f, vectors[index*6+1]*0.3f);
//				pts->InsertNextPoint(x-vectors[index*6+0]*0.3f, y-vectors[index*6+2]*0.3f, -vectors[index*6+1]*0.3f);
//				
//				unsigned char color[3];
//				color[0] = (unsigned char)(fabs(vectors[index*6+0]) * 255.0f);
//				color[1] = (unsigned char)(fabs(vectors[index*6+1]) * 255.0f);
//				color[2] = (unsigned char)(fabs(vectors[index*6+2]) * 255.0f);
//				colors->InsertNextTupleValue(color);
//				count++;
//
//				if ((fabs(vectors[index*6+3]) + fabs(vectors[index*6+3]) + fabs(vectors[index*6+5])) > 0.1f) {
//					pts->InsertNextPoint(x+vectors[index*6+3]*0.3f, y+vectors[index*6+5]*0.3f, vectors[index*6+4]*0.3f);
//					pts->InsertNextPoint(x-vectors[index*6+3]*0.3f, y-vectors[index*6+5]*0.3f, -vectors[index*6+4]*0.3f);
//
//					unsigned char color[3];
//					color[0] = (unsigned char)(fabs(vectors[index*6+3]) * 255.0f);
//					color[1] = (unsigned char)(fabs(vectors[index*6+4]) * 255.0f);
//					color[2] = (unsigned char)(fabs(vectors[index*6+5]) * 255.0f);
//					colors->InsertNextTupleValue(color);
//					count++;
//				}
//			}
//		}
//	}
//
//	vtkPolyData *vectorField = vtkPolyData::New();
//	vectorField->Initialize();
//	vectorField->Allocate();
//	vectorField->SetPoints(pts);
//	for (int i = 0; i < count; ++i) {
//		vtkIdType connectivity[2]; 
//		connectivity[0] = i * 2; 
//		connectivity[1] = i * 2 + 1; 
//		vectorField->InsertNextCell(VTK_LINE,2,connectivity);
//	}
//	vectorField->GetCellData()->SetScalars(colors);
//	vectorField->Update();
//
//	vtkTubeFilter *tube = vtkTubeFilter::New();
//	tube->SetInput(vectorField);
//	tube->SetRadius(.05); //default is .5
//	tube->SetNumberOfSides(16);
//	tube->Update();
//
//    vtkPolyDataMapper *pPolyDataMapper = vtkPolyDataMapper::New();
//    //pPolyDataMapper->SetInput(vectorField);
//	pPolyDataMapper->SetInputConnection(tube->GetOutputPort());
//
//    vtkActor *pActor = vtkActor::New();
//	pActor->SetMapper(pPolyDataMapper);
//	pActor->GetProperty()->SetAmbient(0.5);
//	pActor->GetProperty()->SetDiffuse(0.2);
//
//    vtkRenderer *pRenderer = vtkRenderer::New();
//    pRenderer->AddActor(pActor);
//	//pRenderer->LightFollowCameraOff();
//	//pRenderer->SetAmbient(1.0, 1.0, 1.0);
//	//pRenderer->RemoveAllLights();
//
//    vtkRenderWindow *pRenderWindow = vtkRenderWindow::New();
//    pRenderWindow->AddRenderer(pRenderer);
//    pRenderWindow->SetSize(1024, 1024);
//
//    vtkRenderWindowInteractor *pRenderWindowInteractor = vtkRenderWindowInteractor::New();
//    pRenderWindowInteractor->SetRenderWindow(pRenderWindow);
//
//    pRenderWindow->Render();
//    pRenderWindowInteractor->Start();
//}